#include "base\utilstring.h"
using namespace Base::String;

std::string UnicodeToGBK(const std::wstring& wstr)
{
    if (wstr.empty())
    {
        return std::string();
    }

    const int size = ::WideCharToMultiByte(936, 0, wstr.c_str(), -1, 0, 0, 0, 0 ); 
    if ( size == 0 ) 
    {
        return std::string();
    }

    char* pDestString = new char[size + 2];
    ::memset( pDestString, 0, (size + 2) * sizeof(char) );
    int ret = ::WideCharToMultiByte( 936, 0, wstr.c_str(), -1, pDestString, size, 0, 0 );
    if( ret == 0 )
    {
        delete[] pDestString;
        return std::string();
    }
    else 
    {
        std::string strOut = pDestString;
        delete[] pDestString;
        return strOut;
    } 
}

std::wstring GBKToUnicode(const std::string& str)
{
    if (str.empty())
    {
        return std::wstring();
    }

    const int size = ::MultiByteToWideChar(936, 0, str.c_str(), -1, 0, 0); 
    if ( size == 0 ) 
    {
        return std::wstring();
    }

    wchar_t* pDestString = new wchar_t[size + 2];
    ::memset( pDestString, 0, (size + 2) * sizeof(wchar_t));
    int ret = ::MultiByteToWideChar( 936, 0, str.c_str(), -1, pDestString, size);
    if( ret == 0 )
    {
        delete[] pDestString;
        return std::wstring();
    }
    else 
    {
        std::wstring strOut = pDestString;
        delete[] pDestString;
        return strOut;
    } 
}

std::wstring Utf8ToUnicode(const char* mbstr)
{
    if(!mbstr)
    {
        return std::wstring();
    }
    wchar_t* wcstr = 0;
    int size = MultiByteToWideChar(CP_UTF8, 0, mbstr, -1, 0, 0);
    wcstr = new wchar_t[size + 1];
    if (!wcstr)
    {
        return std::wstring();
    }
    memset(wcstr, 0, size * sizeof(wchar_t));
    int ret = MultiByteToWideChar(CP_UTF8, 0, mbstr, -1, wcstr, size);
    if (!ret)
    {
        delete []wcstr;
        wcstr = 0;
        return std::wstring();
    }
    std::wstring str = wcstr;
    delete []wcstr;
    return str;
}

std::string UnicodetoUtf8(const wchar_t* wcstr)
{
    if (!wcstr)
    {
        return std::string();
    }
    char* mbstr = 0;
    int size = WideCharToMultiByte(CP_UTF8, 0, wcstr, -1, 0, 0, 0, 0);
    mbstr = new char[size+1];
    if (!mbstr)
    {
        return std::string();
    }
    memset(mbstr, 0, size * sizeof(char));
    int ret = WideCharToMultiByte(CP_UTF8, 0, wcstr, -1, mbstr, size, 0, 0);
    if (!ret)
    {
        delete[] mbstr;
        mbstr = 0;
        return std::string();
    }

    std::string str = mbstr;
    delete[] mbstr;
    return str;
}


std::wstring AnsiToUnicode(const char* mbstr)
{
    if (!mbstr)
    {
        return std::wstring();
    }

    wchar_t* wcstr = NULL;
    int size = MultiByteToWideChar(CP_ACP, 0, mbstr, -1, 0, 0);
    wcstr = new wchar_t[size+1];
    if (!wcstr)
    {
        return std::wstring();
    }
    memset(wcstr, 0, size * sizeof(wchar_t));
    int ret = MultiByteToWideChar(CP_ACP, 0, mbstr, -1, wcstr, size);
    if (!ret)
    {
        delete[] wcstr;
        wcstr = 0;
        return std::wstring();
    }

    std::wstring str = wcstr;
    delete[] wcstr;
    return str;
}

std::string GBKToUtf8(const std::string& str)
{
    return std::string();
    //return Base::String::UnicodetoUtf8(Base::String::GBKToUnicode(str).c_str());
}

std::string IntToString(int n)
{
    char tmp[64];
    _itoa_s(n, tmp, 64, 10);
    return std::string(tmp);
}

std::string DWordToString(DWORD dw)
{
    char tmp[64];
    _ultoa_s(dw, tmp, 64, 10);
    return std::string(tmp);
}

std::string Int64ToString(INT64 i64Value)
{
    char tmp[64];
    _i64toa_s(i64Value, tmp, 64, 10);
    return std::string(tmp);
}

std::string UnsignedInt64ToString(UINT64 u64Value)
{
    char tmp[64];
    _ui64toa_s(u64Value, tmp, 64, 10);
    return std::string(tmp);
}

int StringToInt(const std::string& strValue)
{
    return atoi(strValue.c_str());
}

DWORD StringToDWORD(const char* strValue)
{
    DWORD dwValue = 0;

    if (!strValue || !*strValue)
    {
        return false;
    }

    while (isspace((int)*strValue))
    {
        strValue ++;
    }
    if (*strValue == '+')
    {
        strValue ++;
    }
    bool bOK = true;
    if (strValue[0] == '0' && (strValue[1]|0x20)=='x')
    {
        strValue += 2;
        for (;;)
        {
            TCHAR ch = *strValue;
            DWORD dwValue2 = 0;
            if (ch >= '0' && ch <= '9')	dwValue2 = dwValue*16 + ch -'0';
            else if (ch>='a' && ch<='f') dwValue2 = dwValue*16 + ch -'a'+10;
            else if (ch>='A' && ch<='F') dwValue2 = dwValue*16 + ch -'A'+10;
            else break;
            if (dwValue2 < dwValue || dwValue >= 268435456) bOK = false;
            dwValue = dwValue2;
            ++strValue;
        }
    }
    else
    {
        while (*strValue >= '0' && *strValue <= '9')
        {
            DWORD dwValue2 = dwValue * 10 + *strValue++ -'0';
            if (dwValue2 < dwValue || dwValue > 429496729) bOK = false;
            dwValue = dwValue2;
        }
    }
    while (*strValue && isspace((BYTE)*strValue)) ++strValue;
    if(bOK && strValue[0] == 0)
    {
        return dwValue;
    }
    else
    {
        return 0;
    }
}

INT64 StringToInt64(const std::string& strValue )
{
    return _atoi64(strValue.c_str());
}

std::string BufferToString(unsigned char* pBuffer, unsigned int size)
{
    std::string strRet;

    if (pBuffer == NULL)
    {
        return strRet;
    }

    unsigned char* pPos = pBuffer;

    for (unsigned int n = 0; n < size; n++)
    {
        char buf[5] = {0};
        _itoa_s(*pPos, buf, 3, 16);

        if (*pPos == 0)
        {
            strRet += "00";
        }
        else if (strlen(buf) == 1)
        {
            strRet += "0";
            strRet += buf;
        }
        else
        {
            strRet += buf;
        }

        pPos++;
    }

    return strRet;
}